package com.supreme.studyserver.service;

import com.supreme.studyserver.entity.Test;
import org.springframework.stereotype.Service;

import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service
public class ReferenceService {

    public void softReference() {
        SoftReference<Test> testSoftRef = new SoftReference<>(new Test().setFirstName("hello").setLastName("world"));
        Objects.requireNonNull(testSoftRef.get()).setLastName("我爱学习");
        System.gc();
        System.out.println(testSoftRef.isEnqueued());
        System.out.println(testSoftRef.get());
    }

    public void weakReference() {
        WeakReference<Test> testSoftRef = new WeakReference<>(new Test().setFirstName("hello").setLastName("world"));
        System.gc();
        System.out.println(testSoftRef.isEnqueued());
        System.out.println(testSoftRef.get());
    }

    private final Map<String, SoftReference<Test>> testSoftCache = new HashMap<>();

    private void pushTestToSoftCache(String firstName, String lastName) {
        final Test test = new Test().setFirstName(firstName).setLastName(lastName);
        SoftReference<Test> wrTest = new SoftReference<>(test);
        testSoftCache.put(firstName, wrTest);
    }

    private Test pullTestToSoftCache(String firstName) {
        final SoftReference<Test> wrTest = testSoftCache.get(firstName);
        if (wrTest == null) {
            return null;
        }

        return wrTest.get();
    }

    public void testSoftReference() {
        pushTestToSoftCache("alex", "aaa");
        pushTestToSoftCache("brown", "bbb");

        try {
            byte[] bytes = new byte[30 * 1024 * 1024];
        } catch (Throwable e) {
            System.out.println(e.getMessage());
        } finally {
            final Test alexTest = pullTestToSoftCache("alex");
            System.out.println(alexTest);

            final Test brownTest = pullTestToSoftCache("brown");
            System.out.println(brownTest);
        }
    }

    private final Map<String, WeakReference<Test>> testWeakCache = new HashMap<>();

    private void pushTestToWeakCache(String firstName, String lastName) {
        final Test test = new Test().setFirstName(firstName).setLastName(lastName);
        WeakReference<Test> wrTest = new WeakReference<>(test);
        testWeakCache.put(firstName, wrTest);
    }

    private Test pullTestToWeakCache(String firstName) {
        final WeakReference<Test> wrTest = testWeakCache.get(firstName);
        if (wrTest == null) {
            return null;
        }

        return wrTest.get();
    }

    public void testWeakReference() {
        pushTestToWeakCache("alex", "aaa");
        pushTestToWeakCache("brown", "bbb");

        System.gc();

        final Test alexTest = pullTestToWeakCache("alex");
        System.out.println(alexTest);

        final Test brownTest = pullTestToWeakCache("brown");
        System.out.println(brownTest);
    }
}
